package com.wzg;

import com.drew.imaging.ImageMetadataReader;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.ExifIFD0Directory;
import com.drew.metadata.exif.ExifSubIFDDirectory;

import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

import org.apache.poi.util.StringUtil;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;

import java.util.List;
import java.util.stream.Collectors;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class Main {
    private static final String PACKAGE_BATCH_PATH = "C:\\img log\\batch.json";
    private static final String MENU_BATCH_PATH = "C:\\img log\\restaurantbatch.json";

    // 在类中添加静态变量记录上传的图片名
    private static JTextArea uploadedFilesDisplay;
    private static List<String> uploadedFileNames = new ArrayList<>();

//    public static Map<String, Integer> batchMap = new HashMap<>();

    public static FoodCategoryManager fcm = new FoodCategoryManager();

    public static String[] sureNames = fcm.getSureNames();

    public static String[] Level4Names = fcm.getLevel4Names();

    public static JLabel displayArea;

    // 创建UserInputData对象
    public static UserInputData inputData = new UserInputData();

    public static FoodCategoryManager foodCategoryManager = new FoodCategoryManager();

    // 定义一个静态变量来保存上一次的路径
    private static String lastOpenedDirectory = null;

    //    private static JFrame uploadFrame = null;
//    private static JFrame getUploadFrame() {
//        if (uploadFrame == null) {
//            uploadFrame = new JFrame("Upload Form");
//            // 初始化窗体组件
//        }
//        return uploadFrame;
//    }
    private static JFrame uploadFrame = null;

    private static JFrame getUploadFrame() {
        uploadFrame = new JFrame("Upload Form");
        return uploadFrame;
    }

    public static List<JButton> uploadButtonList = new ArrayList<>();


    // 辅助方法：添加表单组件
    private static void addFormComponent(JPanel frame, JPanel panel, GridBagConstraints gbc, int x, int y) {
        gbc.gridx = x;
        gbc.gridy = y;
//        gbc.gridwidth = 2;
        panel.setPreferredSize(new Dimension(200, 25));
        frame.add(panel, gbc);
    }

    // 辅助方法：创建带标题的分组面板
    private static JPanel createGroupPanel(String title) {
        JPanel panel = new JPanel();
        panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), title, TitledBorder.LEFT, TitledBorder.TOP));
        panel.setBackground(new Color(248, 248, 248));
        return panel;
    }

    private static void filterCategories(JComboBox<String> categoryComboBox, String[] categories, String filterText) {
        String[] filterStrings = Arrays.stream(categories).filter(category -> category.toLowerCase().contains(filterText.toLowerCase())).toArray(String[]::new);
        categoryComboBox.setModel(new DefaultComboBoxModel<>(filterStrings));
    }

    public static void main(String[] args) {
        // 创建并显示窗体
        SwingUtilities.invokeLater(() -> {
            // 第一个窗体
            JFrame frame = new JFrame("User Input Form");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(800, 600);
            frame.setLocationRelativeTo(null);

            // 使用主面板
            JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
            mainPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));

            // 创建FoodCategoryManager对象
//            FoodCategoryManager foodCategoryManager = new FoodCategoryManager("com/wzg/json/result.json");
//            InputStream is = ResourceLoader.class.getResourceAsStream("/com/wzg/json/result.json");

            // 创建下拉列表
            String[] allCountries = {"UK", "Australia", "Canada", "New Zealand", "South Africa", "Ireland", "India", "Singapore", "Mainland China", "Malaysia", "Brazil", "Portugal", "Italy", "Switzerland", "France", "Belgium", "Germany"};
            String[] languages = {"Arabic", "Danish", "Dutch", "English (Non-US)", "Finnish", "French", "German", "Hebrew", "Hindi", "Italian", "Japanese", "Korean", "Malaysian", "Norwegian", "Portuguese", "Simplified Chinese", "Spanish", "Swedish", "Thai", "Traditional Chinese", "Turkish", "Vietnamese"};

            String[] level1Categories = foodCategoryManager.getlevel1Names();
            String[] locations = {"Restaurants", "Home", "Other", "Grocery Stores"};
            String[] locationTypes = {"Indoor", "Outdoor"};
            String[] lighting = {"Natural Light", "Artificial Light", "Dim", "Bright", "Other"};
            String[] aggressors = {"", "Light glare", "Occlusion", "Text is distorted (shape of the package or wrinkles)", "Text not legible (small text)", "Text is rotated or tilted", "Low light", "Blur"};

            DefaultComboBoxModel<String> countryModel = new DefaultComboBoxModel<>(allCountries);
            JComboBox<String> countryComboBox = new JComboBox<>(countryModel);
            JComboBox<String> languageComboBox = new JComboBox<>(languages);

            JComboBox<String> level1CategoriesComboBox = new JComboBox<>(level1Categories);
            JComboBox<String> locationComboBox = new JComboBox<>(locations);
            JPanel locationComboBoxPanel = new FormField("Location:", locationComboBox).createPanel();
            JComboBox<String> locationTypeComboBox = new JComboBox<>(locationTypes);
            // 设置Location Type的默认值
            locationTypeComboBox.setSelectedItem("Indoor");
            JPanel locationTypeComboBosPanel = new FormField("Location Type:", locationTypeComboBox).createPanel();

            JComboBox<String> lightingComboBox = new JComboBox<>(lighting);
            // 设置Lighting的默认值
            lightingComboBox.setSelectedItem("Natural Light");
            JPanel lightingComboBoxPanel = new FormField("Lighting:", lightingComboBox).createPanel();

            JComboBox<String> aggressorsComboBox = new JComboBox<>(aggressors);
//            aggressorsComboBox.setSelectedItem("");
            JPanel aggressorsComboBoxPanel = new FormField("Aggressors:", aggressorsComboBox).createPanel();

            // 创建文本字段
            JTextField participantIdField = new JTextField();
//            frame.add(participantIdField);
            JTextField shortDescriptionField = new JTextField();
            JTextField locationOtherField = new JTextField();
            JPanel locationOtherFieldPanel = new FormField("Location if Other:", locationOtherField).createPanel();
            JTextField packageMaterialOtherField = new JTextField();
            JPanel packageMaterialOtherFieldPanel = new FormField("Package Material if Other:", packageMaterialOtherField).createPanel();
            JTextField restaurantMenuField = new JTextField();
            JPanel restaurantMenuFieldPanel = new FormField("Restaurant (Menu Only):", restaurantMenuField).createPanel();
            JTextField menuMaterialOtherField = new JTextField();
            JPanel menuMaterialOtherFieldPanel = new FormField("Menu Material if Other:", menuMaterialOtherField).createPanel();
            //创建临时输入框供category临时筛选使用
            JTextField findCategoryField = new JTextField();

            // 创建新的下拉列表
            String[] packageTypes = {"Box", "Bags", "Bottles", "Cans", "Other"};
//            String[] imageOfPackages = {"Front", "Back"};
            String[] packageMaterials = {"Paper", "Glass", "Other"};
            String[] menuMaterials = {"Paper", "Screen", "Tablet", "Digital/Screenshot", "Other"};
            String[] cuisineCountryOrigins = {"Europe_Greece & Cyprus", "Europe_Scandinavia", "Europe_Eastern Europe", "Europe_Germany", "Europe_Spain", "Europe_Italy", "Europe_France", "Europe_United Kingdom", "North America_United States", "North America_Canada", "North America_Mexico", "North America_Central America", "North America_Carribean", "South America_Argentina", "South America_Uruguay", "South America_Chile", "South America_Peru", "South America_Bolivia", "South America_Brazil", "Asia_China", "Asia_Japan", "Asia_Korea", "Asia_Thailand", "Asia_Vietnam", "Asia_India", "Asia_Iran", "Asia_Mediterranean", "Africa_West Africa", "Africa_North Africa", "Africa_Horn of Africa"};
            JComboBox<String> packageTypeComboBox = new JComboBox<>(packageTypes);
            JPanel packageTypeComboBoxPanel = new FormField("Package Type:", packageTypeComboBox).createPanel();
            JTextField packageTypeIfOtherField = new JTextField();
            JPanel packageTypeIfOtherFieldFieldPanel = new FormField("Package Type if Other:", packageTypeIfOtherField).createPanel();
/*            JComboBox<String> imageOfPackageComboBox = new JComboBox<>(imageOfPackages);
            JPanel imageOfPackageComboBoxPanel = new FormField("Image of Package:", imageOfPackageComboBox).createPanel();*/
            JComboBox<String> packageMaterialComboBox = new JComboBox<>(packageMaterials);
            JPanel packageMaterialComboBoxPanel = new FormField("Package Material:", packageMaterialComboBox).createPanel();
            JComboBox<String> menuMaterialComboBox = new JComboBox<>(menuMaterials);
            JPanel menuMaterialComboBoxPanel = new FormField("Menu Material:", menuMaterialComboBox).createPanel();
            JComboBox<String> cuisineCountryOriginComboBox = new JComboBox<>(cuisineCountryOrigins);
            JButton findButton = new JButton("find");
            // 创建Prev按钮
            JButton prevButton = new JButton("返回");
            // 创建确定按钮
            JButton confirmButton = new JButton("确定");


            // 1. 用户信息组
            JPanel userInfoPanel = createGroupPanel("First input");
            userInfoPanel.setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.insets = new Insets(5, 5, 5, 5);
            gbc.anchor = GridBagConstraints.WEST;

            // 参与者ID
            gbc.gridx = 0;
            gbc.gridy = 0;
            userInfoPanel.add(new JLabel("Participant ID:"), gbc);
            gbc.gridx = 1;
            participantIdField.setPreferredSize(new Dimension(200, 25));
            userInfoPanel.add(participantIdField, gbc);

            // 国家选择
            gbc.gridx = 0;
            gbc.gridy = 1;
            userInfoPanel.add(new JLabel("Country:"), gbc);
            gbc.gridx = 1;
            countryComboBox.setPreferredSize(new Dimension(200, 25));
            userInfoPanel.add(countryComboBox, gbc);

            // 语言选择
            gbc.gridx = 0;
            gbc.gridy = 2;
            userInfoPanel.add(new JLabel("Language:"), gbc);
            gbc.gridx = 1;
            languageComboBox.setPreferredSize(new Dimension(200, 25));
            userInfoPanel.add(languageComboBox, gbc);

            // 2. 分类信息组
            JPanel categoryPanel = createGroupPanel("Second input");
            categoryPanel.setLayout(new GridBagLayout());

            // Level 1分类
            gbc.gridx = 0;
            gbc.gridy = 0;
            categoryPanel.add(new JLabel("Level 1 Category:"), gbc);
            gbc.gridx = 1;
//            level1CategoriesComboBox.setPreferredSize(new Dimension(200, 25));
            categoryPanel.add(level1CategoriesComboBox, gbc);

            // 菜系/原产国
            gbc.gridx = 0;
            gbc.gridy = 1;
            categoryPanel.add(new JLabel("Cuisine/Country of Origin:"), gbc);
            gbc.gridx = 1;
//            cuisineCountryOriginComboBox.setPreferredSize(new Dimension(200, 25));
            categoryPanel.add(cuisineCountryOriginComboBox, gbc);

            // 创建Next按钮
            JButton nextButton = new JButton("Next");
            JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 10));
            nextButton.setPreferredSize(new Dimension(100, 30));
            buttonPanel.add(nextButton);

            // 组装主面板
            mainPanel.add(userInfoPanel, BorderLayout.NORTH);
            mainPanel.add(categoryPanel, BorderLayout.CENTER);
            mainPanel.add(buttonPanel, BorderLayout.SOUTH);

            frame.add(mainPanel);
            frame.setVisible(true);  // 确保最后才显示窗体


            // 隐藏新添加的组件
            packageTypeComboBoxPanel.setVisible(false);
//            imageOfPackageComboBoxPanel.setVisible(false);
            packageMaterialComboBoxPanel.setVisible(false);
            packageMaterialOtherFieldPanel.setVisible(false);
            packageTypeIfOtherFieldFieldPanel.setVisible(false);
            locationOtherFieldPanel.setVisible(false);
            restaurantMenuFieldPanel.setVisible(false);
            menuMaterialComboBoxPanel.setVisible(false);
            menuMaterialOtherFieldPanel.setVisible(false);


            level1CategoriesComboBox.addItemListener(e -> {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    String selectedCategory = (String) level1CategoriesComboBox.getSelectedItem();
                    boolean isMenu = "Menu".equals(selectedCategory);
                    packageTypeComboBoxPanel.setVisible(!isMenu);
//                    imageOfPackageComboBoxPanel.setVisible(!isMenu);
                    packageMaterialComboBoxPanel.setVisible(!isMenu);
                    packageMaterialOtherFieldPanel.setVisible(false);
                    packageTypeIfOtherFieldFieldPanel.setVisible(false);
                    restaurantMenuFieldPanel.setVisible(isMenu);
                    menuMaterialComboBoxPanel.setVisible(isMenu);
                    menuMaterialOtherFieldPanel.setVisible(false);

                    // 设置Location的默认值
                    if (isMenu) {
                        locationComboBox.setSelectedItem("Restaurants");
                    } else {
                        locationComboBox.setSelectedItem("Grocery Stores");
                    }
                }
            });

            // 添加包材选择监听器
            packageMaterialComboBox.addItemListener(e -> {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    String selectedMaterial = (String) packageMaterialComboBox.getSelectedItem();
                    boolean isOther = "Other".equals(selectedMaterial);
                    packageMaterialOtherFieldPanel.setVisible(isOther);
                }
            });

            // 添加地点选择监听器
            locationComboBox.addItemListener(e -> {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    String selectedLocation = (String) locationComboBox.getSelectedItem();
                    boolean isOther = "Other".equals(selectedLocation);
                    locationOtherFieldPanel.setVisible(isOther);
                }
            });

            // 添加Menu Material选择监听器
            menuMaterialComboBox.addItemListener(e -> {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    String selectedMaterial = (String) menuMaterialComboBox.getSelectedItem();
                    boolean isOther = "Other".equals(selectedMaterial);
                    menuMaterialOtherFieldPanel.setVisible(isOther);
                }
            });

            //packageType
            packageTypeComboBox.addItemListener(e -> {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    String selectedMaterial = (String) packageTypeComboBox.getSelectedItem();
                    boolean isOther = "Other".equals(selectedMaterial);
                    packageTypeIfOtherFieldFieldPanel.setVisible(isOther);
                }
            });

            // 添加Country选择监听器
            countryComboBox.addItemListener(e -> {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    String selectedCountry = (String) countryComboBox.getSelectedItem();
                    for (String origin : cuisineCountryOrigins) {
                        if (origin.contains(selectedCountry)) {
                            cuisineCountryOriginComboBox.setSelectedItem(origin);
                            break;
                        }
                    }
                }
            });


            List<UserInputData> userInputList = new ArrayList<>();


            nextButton.addActionListener(e -> {
                extracted(frame, countryComboBox, languageComboBox, level1CategoriesComboBox, locationComboBox, locationComboBoxPanel, locationTypeComboBox, locationTypeComboBosPanel, lightingComboBox, lightingComboBoxPanel, participantIdField, shortDescriptionField, locationOtherField, locationOtherFieldPanel, packageMaterialOtherField, packageMaterialOtherFieldPanel, restaurantMenuField, restaurantMenuFieldPanel, menuMaterialOtherField, menuMaterialOtherFieldPanel, findCategoryField, packageTypeComboBox, packageTypeComboBoxPanel, packageMaterialComboBox, packageMaterialComboBoxPanel, menuMaterialComboBox, menuMaterialComboBoxPanel, cuisineCountryOriginComboBox, findButton, prevButton, confirmButton, userInputList, aggressorsComboBoxPanel, packageTypeIfOtherFieldFieldPanel, packageTypeIfOtherField, aggressorsComboBox);
            });


            // 添加按钮点击监听器
            prevButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // 移除所有已有的监听器
                    for (ActionListener al : nextButton.getActionListeners()) {
                        nextButton.removeActionListener(al);
                    }
                    for (ActionListener al : findButton.getActionListeners()) {
                        findButton.removeActionListener(al);
                    }
                    for (ActionListener al : confirmButton.getActionListeners()) {
                        confirmButton.removeActionListener(al);
                    }
                    for (JButton uploadButton : uploadButtonList) {
                        for (ActionListener al : uploadButton.getActionListeners()) {
                            uploadButton.removeActionListener(al);
                        }
                    }
                    inputData = new UserInputData();
                    userInputList.clear();
                    uploadButtonList.clear();
                    // 关闭窗体
                    uploadFrame.dispose();
                    // 清除 uploadFrame 上的所有数据
                    clearUploadFrameData(uploadFrame);
                    uploadedFileNames.clear();
                    uploadedFilesDisplay.removeAll();

                    nextButton.addActionListener(e22 -> {
                        extracted(frame, countryComboBox, languageComboBox, level1CategoriesComboBox, locationComboBox, locationComboBoxPanel, locationTypeComboBox, locationTypeComboBosPanel, lightingComboBox, lightingComboBoxPanel, participantIdField, shortDescriptionField, locationOtherField, locationOtherFieldPanel, packageMaterialOtherField, packageMaterialOtherFieldPanel, restaurantMenuField, restaurantMenuFieldPanel, menuMaterialOtherField, menuMaterialOtherFieldPanel, findCategoryField, packageTypeComboBox, packageTypeComboBoxPanel, packageMaterialComboBox, packageMaterialComboBoxPanel, menuMaterialComboBox, menuMaterialComboBoxPanel, cuisineCountryOriginComboBox, findButton, prevButton, confirmButton, userInputList, aggressorsComboBoxPanel, packageTypeIfOtherFieldFieldPanel, packageTypeIfOtherField, aggressorsComboBox);
                    });


//                        uploadFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//                        uploadFrame.setSize(700, 800);
//                        uploadFrame.setLayout(new GridLayout(0, 2));
//                        uploadFrame.setVisible(false);
//                        uploadFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);

                    // 重新布局
//                        uploadFrame.revalidate();
//                        uploadFrame.repaint();
//                        uploadFrame.setVisible(false);

                    // 显示主窗体
                    frame.setVisible(true);
                }
            });

        });
    }

    private static void extracted(JFrame frame, JComboBox<String> countryComboBox, JComboBox<String> languageComboBox, JComboBox<String> level1CategoriesComboBox, JComboBox<String> locationComboBox, JPanel locationComboBoxPanel, JComboBox<String> locationTypeComboBox, JPanel locationTypeComboBosPanel, JComboBox<String> lightingComboBox, JPanel lightingComboBoxPanel, JTextField participantIdField, JTextField shortDescriptionField, JTextField locationOtherField, JPanel locationOtherFieldPanel, JTextField packageMaterialOtherField, JPanel packageMaterialOtherFieldPanel, JTextField restaurantMenuField, JPanel restaurantMenuFieldPanel, JTextField menuMaterialOtherField, JPanel menuMaterialOtherFieldPanel, JTextField findCategoryField, JComboBox<String> packageTypeComboBox, JPanel packageTypeComboBoxPanel, JComboBox<String> packageMaterialComboBox, JPanel packageMaterialComboBoxPanel, JComboBox<String> menuMaterialComboBox, JPanel menuMaterialComboBoxPanel, JComboBox<String> cuisineCountryOriginComboBox, JButton findButton, JButton prevButton, JButton confirmButton, List<UserInputData> userInputList, JPanel aggressorsComboBoxPanel, JPanel packageTypeIfOtherFieldFieldPanel, JTextField packageTypeIfOtherField, JComboBox<String> aggressorsComboBox) {
        frame.setVisible(false);

        // 校验必填字段
        if (countryComboBox.getSelectedItem() == null || countryComboBox.getSelectedItem().toString().isEmpty()) {
            JOptionPane.showMessageDialog(frame, "Country is required.", "Error", JOptionPane.ERROR_MESSAGE);
            return;
        }
        if (languageComboBox.getSelectedItem() == null || languageComboBox.getSelectedItem().toString().isEmpty()) {
            JOptionPane.showMessageDialog(frame, "Language is required.", "Error", JOptionPane.ERROR_MESSAGE);
            return;
        }
        if (participantIdField.getText().isEmpty()) {
            JOptionPane.showMessageDialog(frame, "Participant ID is required.", "Error", JOptionPane.ERROR_MESSAGE);
            return;
        }
        if (cuisineCountryOriginComboBox.getSelectedItem() == null || cuisineCountryOriginComboBox.getSelectedItem().toString().isEmpty()) {
            JOptionPane.showMessageDialog(frame, "Cuisine/Country of Origin is required.", "Error", JOptionPane.ERROR_MESSAGE);
            return;
        }


        // 存储当前窗体上的数据到UserInputData对象中
        inputData.setParticipantId(participantIdField.getText());
        inputData.setCountry((String) countryComboBox.getSelectedItem());
        inputData.setLanguage((String) languageComboBox.getSelectedItem());
        inputData.setLevel1Category((String) level1CategoriesComboBox.getSelectedItem());
        inputData.setCuisineCountryOfOrigin((String) cuisineCountryOriginComboBox.getSelectedItem());
        //=================================================================================================

        //第二个窗体
//                JFrame uploadFrame = new JFrame("Upload Form");
        JFrame uploadFrame = getUploadFrame();
        uploadFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        uploadFrame.setSize(800, 600);
        uploadFrame.setLocationRelativeTo(null);
        uploadFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);
//                uploadFrame.setLayout(new GridBagLayout());

        // 使用第二个窗体的主面板
        JPanel uploadMainPanel = new JPanel(new BorderLayout(10, 10));
        uploadMainPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));


        GridBagConstraints uploadGbc = new GridBagConstraints();
        JPanel xxPanel = createGroupPanel("选项");
        xxPanel.setLayout(new GridBagLayout());


        //图片上传组列表
        JPanel imgUpPanel = createGroupPanel("已上传的图片");
        imgUpPanel.setLayout(new GridBagLayout());

        //图片上传组列表
        JPanel seePanel = createGroupPanel("查看图片");
        seePanel.setLayout(new GridBagLayout());

        uploadGbc.insets = new Insets(5, 5, 5, 5);
        uploadGbc.anchor = GridBagConstraints.WEST;
//                uploadGbc.fill = GridBagConstraints.HORIZONTAL;

        String[] categories = foodCategoryManager.getCategoriesByLevel1Names(inputData.getLevel1Category());
        JComboBox<String> categoryComboBox = new JComboBox<>(categories);
        uploadGbc.gridx = 0;
        uploadGbc.gridy = 0;
//                xxPanel.add(new JLabel("Level 4 Category:"), uploadGbc);
        JPanel level4BoxPanel = new FormField("Level 4 Category:", categoryComboBox).createPanel();
        xxPanel.add(level4BoxPanel, uploadGbc);
//                uploadGbc.gridx = 1;
//                categoryComboBox.setPreferredSize(new Dimension(200, 25));
//                xxPanel.add(categoryComboBox, uploadGbc);

        JPanel findPanel = new JPanel(new GridBagLayout());
        uploadGbc.gridx = 1;
        uploadGbc.gridy = 0;
//                uploadFrame.add(new JLabel("搜索分类:"), uploadGbc);
        findCategoryField.setPreferredSize(new Dimension(200, 25));
        findPanel.add(findCategoryField);
        findPanel.add(findButton);
        xxPanel.add(findPanel, uploadGbc);
//                uploadGbc.gridx = 2;
//                uploadGbc.gridy = 0;
//                xxPanel.add(findButton, uploadGbc);

        //先给这几个赋值
        FoodCategory fc = foodCategoryManager.getCategoryBySureName((String) categoryComboBox.getSelectedItem());
        inputData.setLevel4Category(fc.getLevel4());
        inputData.setLevel3Category(fc.getLevel3());
        inputData.setLevel2Category(fc.getLevel2());

//                uploadFrame.add(findButton);
        findButton.addActionListener(e1 -> {
            String findCategory = findCategoryField.getText();
            filterCategories(categoryComboBox, categories, findCategory);
        });

        // 添加Short Description标签和文本框到窗体
        JPanel shortDescriptionFieldPanel = new FormField("Short Description:", shortDescriptionField).createPanel();
//                addFormComponent(xxPanel, shortDescriptionFieldPanel, uploadGbc, 0, 1);
        uploadGbc.gridx = 0;
        uploadGbc.gridy = 1;
        shortDescriptionFieldPanel.setPreferredSize(new Dimension(500, 25));
        xxPanel.add(shortDescriptionFieldPanel, uploadGbc);
        addFormComponent(xxPanel, locationComboBoxPanel, uploadGbc, 1, 1);
        addFormComponent(xxPanel, locationOtherFieldPanel, uploadGbc, 0, 2);
        addFormComponent(xxPanel, locationTypeComboBosPanel, uploadGbc, 1, 2);
        addFormComponent(xxPanel, packageTypeComboBoxPanel, uploadGbc, 0, 3);
        addFormComponent(xxPanel, packageTypeIfOtherFieldFieldPanel, uploadGbc, 1, 3);
//                addFormComponent(xxPanel, imageOfPackageComboBoxPanel, uploadGbc, 1, 3);
        addFormComponent(xxPanel, packageMaterialComboBoxPanel, uploadGbc, 0, 4);
        addFormComponent(xxPanel, packageMaterialOtherFieldPanel, uploadGbc, 1, 4);
        uploadGbc.gridx = 0;
        uploadGbc.gridy = 5;
        restaurantMenuFieldPanel.setPreferredSize(new Dimension(500, 25));
        xxPanel.add(restaurantMenuFieldPanel, uploadGbc);
        addFormComponent(xxPanel, menuMaterialComboBoxPanel, uploadGbc, 1, 5);
        addFormComponent(xxPanel, menuMaterialOtherFieldPanel, uploadGbc, 0, 6);
        addFormComponent(xxPanel, lightingComboBoxPanel, uploadGbc, 1, 6);
        uploadGbc.gridx = 0;
        uploadGbc.gridy = 7;
        xxPanel.add(aggressorsComboBoxPanel, uploadGbc);
//        addFormComponent(xxPanel, aggressorsComboBoxPanel, uploadGbc, 0, 7);
        //=================================================================================================

        //put批次的map
        String participantId = participantIdField.getText();
        String category = (String) categoryComboBox.getSelectedItem();
        String l4bsn = fcm.getLevel4BySureName(category);
        String key = participantId + "_" + l4bsn;

        displayArea = new JLabel();
        if (!"Menu".equals(fcm.getLevel4BySureName(category))){
//            JSONObject batchJson = readBatchJson(MENU_BATCH_PATH);
//            JSONArray menuSetJsonArray = batchJson.optJSONArray(participantId);
            JSONObject batchJson = readBatchJson(PACKAGE_BATCH_PATH);
            // 查询并更新JSON数据
            int value = batchJson.optInt(key, 0) + 1;
                /*batchJson.put(key, value);

                // 写回JSON文件
                writeBatchJson(batchJson);*/
            // 创建文本展示框
            displayArea.setText("Unique Identifier: " + key + ", Image Grouping: " + value);
            displayArea.setPreferredSize(new Dimension(600, 25));
        }


        uploadGbc.gridx = 0;
        uploadGbc.gridy = 8;
        xxPanel.add(displayArea, uploadGbc);
        /*JLabel promptLabel = new JLabel("请务必将以上所有需要填的信息填完再上传图片，否则会导致图片内容有误！");
        promptLabel.setForeground(Color.RED);
        uploadGbc.gridx = 1;
        uploadGbc.gridy = 8;
        xxPanel.add(promptLabel, uploadGbc);*/
        //==========================================================================

        uploadMainPanel.add(xxPanel, BorderLayout.NORTH);


        // 添加类别选择监听器
        categoryComboBox.addItemListener(e1 -> {
            if (e1.getStateChange() == ItemEvent.SELECTED) {

                FoodCategory fc1 = foodCategoryManager.getCategoryBySureName((String) categoryComboBox.getSelectedItem());
                inputData.setLevel4Category(fc1.getLevel4());
                inputData.setLevel3Category(fc1.getLevel3());
                inputData.setLevel2Category(fc1.getLevel2());

                String participantIdChanged = participantIdField.getText();
                String categoryChanged = (String) categoryComboBox.getSelectedItem();
                String key1 = participantIdChanged + "_" + fcm.getLevel4BySureName(categoryChanged);
                if (!fc1.getLevel4().equals("Menu")){
                    // 查询数据
                    JSONObject batchJsonLis = readBatchJson(PACKAGE_BATCH_PATH);
                    // 查询并更新JSON数据
                    int value1 = batchJsonLis.optInt(key1, 0) + 1;
                    displayArea.setText("Unique Identifier: " + key1 + ", Image Grouping: " + value1);
                }

                uploadFrame.revalidate();
                uploadFrame.repaint();
            }
        });

        restaurantMenuField.addActionListener(e1 -> {
            String pid = participantIdField.getText();
            String restaurantMenu = restaurantMenuField.getText();
            JSONObject batchJsonLis = readBatchJson(MENU_BATCH_PATH);
            JSONArray menuBatchSetJSONArray = batchJsonLis.optJSONArray(pid);
            Set<String> reSet = new LinkedHashSet<>();
            if (menuBatchSetJSONArray != null){
                reSet = menuBatchSetJSONArray.toList().stream().map(Object::toString).collect(Collectors.toCollection(LinkedHashSet::new));
            }
            reSet.add(restaurantMenu);
            batchJsonLis.put(pid, reSet);
            int index = findIndex(reSet, restaurantMenu)+1;
//            writeBatchJson(batchJsonLis, MENU_BATCH_PATH);
            displayArea.setText("Unique Identifier: " + key + ", Image Grouping: " + index);
            displayArea.setPreferredSize(new Dimension(600, 25));
            uploadFrame.revalidate();
            uploadFrame.repaint();

        });


//========================================================================================

        JPanel upButtonPanel = new JPanel();
        upButtonPanel.setLayout(new GridBagLayout());

/*                JPanel frontPanel = createGroupPanel("Front");
                frontPanel.setLayout(new GridBagLayout());

                JPanel backPanel = createGroupPanel("Back");
                backPanel.setLayout(new GridBagLayout());

                uploadGbc.gridx = 0;
                uploadGbc.gridy = 8;
                xxPanel.add(frontPanel,uploadGbc);
                uploadGbc.gridx = 1;
                xxPanel.add(backPanel,uploadGbc);*/

        // 根据Level 4 Category的值显示不同的内容
        String selectedCategory = inputData.getLevel4Category();
        if ("Menu".equals(selectedCategory)) {
            // 显示两个上传图片的输入框
            UserInputData normal = addImageUploadComponents(uploadFrame, "Normal", inputData, xxPanel, 0, 9, uploadGbc,
                    locationComboBox, locationOtherField, locationTypeComboBox, packageTypeComboBox, categoryComboBox,
                    packageMaterialComboBox, packageMaterialOtherField, restaurantMenuField, menuMaterialComboBox,
                    menuMaterialOtherField, lightingComboBox, shortDescriptionField, upButtonPanel, 1, packageTypeIfOtherField, aggressorsComboBox);

            normal.setScanType("Normal");
            UserInputData freeform = addImageUploadComponents(uploadFrame, "Freeform", inputData, xxPanel, 1, 9, uploadGbc, locationComboBox, locationOtherField, locationTypeComboBox, packageTypeComboBox, categoryComboBox,
                    packageMaterialComboBox, packageMaterialOtherField, restaurantMenuField, menuMaterialComboBox,
                    menuMaterialOtherField, lightingComboBox, shortDescriptionField, upButtonPanel, 2, packageTypeIfOtherField, aggressorsComboBox);
            freeform.setScanType("Freeform");
            userInputList.add(normal);
            userInputList.add(freeform);
        } else {
            inputData.setImageOfPackage("Front");
            // 显示四个上传图片的输入框和一个名为“添加Barcode”的按钮
            UserInputData normal1 = addImageUploadComponents(uploadFrame, "Normal1", inputData, xxPanel, 0, 10, uploadGbc, locationComboBox, locationOtherField, locationTypeComboBox, packageTypeComboBox, categoryComboBox,
                    packageMaterialComboBox, packageMaterialOtherField, restaurantMenuField, menuMaterialComboBox,
                    menuMaterialOtherField, lightingComboBox, shortDescriptionField, upButtonPanel, 1, packageTypeIfOtherField, aggressorsComboBox);
            inputData.setImageOfPackage("Back");
            UserInputData normal2 = addImageUploadComponents(uploadFrame, "Normal2", inputData, xxPanel, 1, 10, uploadGbc, locationComboBox, locationOtherField, locationTypeComboBox, packageTypeComboBox, categoryComboBox,
                    packageMaterialComboBox, packageMaterialOtherField, restaurantMenuField, menuMaterialComboBox,
                    menuMaterialOtherField, lightingComboBox, shortDescriptionField, upButtonPanel, 2, packageTypeIfOtherField, aggressorsComboBox);
            inputData.setImageOfPackage("Front");
            UserInputData freeform1 = addImageUploadComponents(uploadFrame, "Freeform1", inputData, xxPanel, 0, 11, uploadGbc, locationComboBox, locationOtherField, locationTypeComboBox, packageTypeComboBox, categoryComboBox,
                    packageMaterialComboBox, packageMaterialOtherField, restaurantMenuField, menuMaterialComboBox,
                    menuMaterialOtherField, lightingComboBox, shortDescriptionField, upButtonPanel, 3, packageTypeIfOtherField, aggressorsComboBox);
            inputData.setImageOfPackage("Back");
            UserInputData freeform2 = addImageUploadComponents(uploadFrame, "Freeform2", inputData, xxPanel, 1, 11, uploadGbc, locationComboBox, locationOtherField, locationTypeComboBox, packageTypeComboBox, categoryComboBox,
                    packageMaterialComboBox, packageMaterialOtherField, restaurantMenuField, menuMaterialComboBox,
                    menuMaterialOtherField, lightingComboBox, shortDescriptionField, upButtonPanel, 4, packageTypeIfOtherField, aggressorsComboBox);
            inputData.setImageOfPackage("Front");
            UserInputData Barcode = addImageUploadComponents(uploadFrame, "Barcode", inputData, xxPanel, 0, 12, uploadGbc, locationComboBox, locationOtherField, locationTypeComboBox, packageTypeComboBox, categoryComboBox,
                    packageMaterialComboBox, packageMaterialOtherField, restaurantMenuField, menuMaterialComboBox,
                    menuMaterialOtherField, lightingComboBox, shortDescriptionField, upButtonPanel, 5, packageTypeIfOtherField, aggressorsComboBox);
            inputData.setImageOfPackage("Back");
            UserInputData me = addImageUploadComponents(uploadFrame, "menu", inputData, xxPanel, 1, 12, uploadGbc, locationComboBox, locationOtherField, locationTypeComboBox, packageTypeComboBox, categoryComboBox,
                    packageMaterialComboBox, packageMaterialOtherField, restaurantMenuField, menuMaterialComboBox,
                    menuMaterialOtherField, lightingComboBox, shortDescriptionField, upButtonPanel, 6, packageTypeIfOtherField, aggressorsComboBox);
            normal1.setScanType("Normal");
            normal2.setScanType("Normal");
            freeform1.setScanType("Freeform");
            freeform2.setScanType("Freeform");
            Barcode.setScanType("Barcode");
            me.setScanType("menu");
            userInputList.add(normal1);
            userInputList.add(normal2);
            userInputList.add(freeform1);
            userInputList.add(freeform2);
            userInputList.add(Barcode);
            userInputList.add(me);
        }


        for (UserInputData userInputData : userInputList) {
            JButton uploadButton = userInputData.getUploadButton();
            uploadButtonList.add(uploadButton);
        }

        uploadedFilesDisplay = new JTextArea(10, 30);
        uploadedFilesDisplay.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(uploadedFilesDisplay);
        uploadGbc.gridx = 0;
        uploadGbc.gridy = 0;
        imgUpPanel.add(scrollPane, uploadGbc);

        uploadGbc.gridx = 0;
        uploadGbc.gridy = 0;
        seePanel.add(upButtonPanel, uploadGbc);

        uploadMainPanel.add(imgUpPanel, BorderLayout.CENTER);
        uploadMainPanel.add(seePanel, BorderLayout.EAST);


//=================================================================================================

        // 按钮区域
        JPanel buttonPanel1 = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));
        // 添加Prev按钮到窗体
        prevButton.setPreferredSize(new Dimension(100, 30));
        buttonPanel1.add(prevButton);
//=================================================================================================


//===================================================================================================

        confirmButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

                if (categoryComboBox.getSelectedItem() == null || categoryComboBox.getSelectedItem().toString().isEmpty()) {
                    JOptionPane.showMessageDialog(frame, "Level 4 Category is required.", "Error", JOptionPane.ERROR_MESSAGE);
                    return;
                }
                if (shortDescriptionField.getText().isEmpty()) {
                    JOptionPane.showMessageDialog(frame, "Short Description is required.", "Error", JOptionPane.ERROR_MESSAGE);
                    return;
                }
                if (locationComboBox.getSelectedItem() == null || locationComboBox.getSelectedItem().toString().isEmpty()) {
                    JOptionPane.showMessageDialog(frame, "Location is required.", "Error", JOptionPane.ERROR_MESSAGE);
                    return;
                }
                if (locationTypeComboBox.getSelectedItem() == null || locationTypeComboBox.getSelectedItem().toString().isEmpty()) {
                    JOptionPane.showMessageDialog(frame, "Location Type is required.", "Error", JOptionPane.ERROR_MESSAGE);
                    return;
                }
                if (lightingComboBox.getSelectedItem() == null || lightingComboBox.getSelectedItem().toString().isEmpty()) {
                    JOptionPane.showMessageDialog(frame, "Lighting is required.", "Error", JOptionPane.ERROR_MESSAGE);
                    return;
                }
                //校验Location如果为Other，那么Location Other的值不能为空
                if ("Other".equals(locationComboBox.getSelectedItem())) {
                    if (locationOtherField.getText().isEmpty()) {
                        JOptionPane.showMessageDialog(frame, "Location Other is required.", "Error", JOptionPane.ERROR_MESSAGE);
                        return;
                    }
                }
                //校验Package Type如果为Other, 那么Package Type Other的值不能为空
                if ("Other".equals(packageTypeComboBox.getSelectedItem())) {
                    if (packageTypeIfOtherField.getText().isEmpty()) {
                        JOptionPane.showMessageDialog(frame, "Package Type If Other is required.", "Error", JOptionPane.ERROR_MESSAGE);
                        return;
                    }
                }
                //校验Package Material如果为Other, 那么Package Material Other的值不能为空
                if ("Other".equals(packageMaterialComboBox.getSelectedItem())) {
                    if (packageMaterialOtherField.getText().isEmpty()) {
                        JOptionPane.showMessageDialog(frame, "Package Material Other is required.", "Error", JOptionPane.ERROR_MESSAGE);
                        return;
                    }
                }

                //筛选userInputList集合中isNewCreated为true的元素
                List<UserInputData> newCreatedUserInputList = userInputList.stream().filter(UserInputData::isNewCreated).toList();

                // 根据Level 4 Category的值进行不同的验证
                String selectedCategory = inputData.getLevel4Category();
                if ("Menu".equals(selectedCategory)) {
                    //校验Restaurant (Menu Only)
                    if (restaurantMenuField.getText().isEmpty()) {
                        JOptionPane.showMessageDialog(uploadFrame, "Restaurant (Menu Only) is required.", "错误", JOptionPane.ERROR_MESSAGE);
                        return;
                    }

                    // 计算filename不为空的元素数量
                    long nonEmptyFilenameCount = newCreatedUserInputList.stream().filter(userInputData -> userInputData.getFilename() != null && !userInputData.getFilename().isEmpty()).count();
                    if (nonEmptyFilenameCount != 2) {
                        JOptionPane.showMessageDialog(uploadFrame, "Menu类别下，上传图片数量必须为2", "错误", JOptionPane.ERROR_MESSAGE);
                        return;
                    }
                    boolean hasNormal = false;
                    boolean hasFreeform = false;
                    for (UserInputData userInputData : newCreatedUserInputList) {
                        if ("Normal".equals(userInputData.getScanType())) {
                            hasNormal = true;
                        } else if ("Freeform".equals(userInputData.getScanType())) {
                            hasFreeform = true;
                        }
                    }
                    if (!hasNormal || !hasFreeform) {
                        JOptionPane.showMessageDialog(uploadFrame, "Menu类别下，必须包含一个Normal和一个Freeform类型的图片", "错误", JOptionPane.ERROR_MESSAGE);
                        return;
                    }
                } else {
                    // 计算filename不为空的元素数量
                    long nonEmptyFilenameCount = newCreatedUserInputList.stream().filter(userInputData -> userInputData.getFilename() != null && !userInputData.getFilename().isEmpty()).count();
                    if (nonEmptyFilenameCount < 4) {
                        JOptionPane.showMessageDialog(uploadFrame, "非Menu类别下，上传图片数量必须至少为4", "错误", JOptionPane.ERROR_MESSAGE);
                        return;
                    }
                    int normalCount = 0;
                    int freeformCount = 0;
                    for (UserInputData userInputData : newCreatedUserInputList) {
                        if ("Normal".equals(userInputData.getScanType())) {
                            normalCount++;
                        } else if ("Freeform".equals(userInputData.getScanType())) {
                            freeformCount++;
                        }
                    }
                    if (normalCount < 2 || freeformCount < 2) {
                        JOptionPane.showMessageDialog(uploadFrame, "非Menu类别下，必须包含至少两个Normal和两个Freeform类型的图片", "错误", JOptionPane.ERROR_MESSAGE);
                        return;
                    }
                }


                // 补齐对象最后的字段。
                for (UserInputData userInputData : newCreatedUserInputList) {
                    if (StringUtil.isNotBlank(userInputData.getFilename())) {
                        userInputData.setLevel4Category((String) categoryComboBox.getSelectedItem());
                        FoodCategory fc = foodCategoryManager.getCategoryBySureName((String) categoryComboBox.getSelectedItem());
                        userInputData.setLevel4Category(fc.getLevel4());
                        userInputData.setLevel3Category(fc.getLevel3());
                        userInputData.setLevel2Category(fc.getLevel2());
                        userInputData.setLocation((String) locationComboBox.getSelectedItem());
                        userInputData.setLocationIfOther(locationOtherField.getText());
                        userInputData.setLocationType((String) locationTypeComboBox.getSelectedItem());
                        userInputData.setPackageType((String) packageTypeComboBox.getSelectedItem());
                        userInputData.setPackageMaterial((String) packageMaterialComboBox.getSelectedItem());
                        userInputData.setPackageMaterialIfOther(packageMaterialOtherField.getText());
                        userInputData.setRestaurantMenu(restaurantMenuField.getText());
                        userInputData.setMenuMaterial((String) menuMaterialComboBox.getSelectedItem());
                        userInputData.setMenuMaterialIfOther(menuMaterialOtherField.getText());
                        userInputData.setPackageTypeIfOther(packageTypeIfOtherField.getText());
//                        userInputData.setAggressors((String) aggressorsComboBox.getSelectedItem());
                        userInputData.setLighting((String) lightingComboBox.getSelectedItem());
                        userInputData.setShortDescription(shortDescriptionField.getText());

                        userInputData.setCameraSetting("Auto");



                        String category4 = userInputData.getLevel4Category();
                        String pid = userInputData.getParticipantId();
                        String key = pid + "_" + category4;

                        //menu和package的imageGrouping生成逻辑不一样
                        if ("Menu".equals(category4)) {
                            // 查询数据
                            JSONObject batchJsonLis = readBatchJson(MENU_BATCH_PATH);
                            JSONArray menuBatchSetJSONArray = batchJsonLis.optJSONArray(pid);
//                            Set<String> reSet = menuBatchSetJSONArray.toList().stream().map(Object::toString).collect(Collectors.toCollection(LinkedHashSet::new));
                            Set<String> reSet = new LinkedHashSet<>();
                            if (menuBatchSetJSONArray != null){
                                reSet = menuBatchSetJSONArray.toList().stream().map(Object::toString).collect(Collectors.toCollection(LinkedHashSet::new));
                            }
                            String restaurantMenu = userInputData.getRestaurantMenu();
                            reSet.add(restaurantMenu);
                            batchJsonLis.put(pid, reSet);
                            int index = findIndex(reSet, restaurantMenu)+1;
                            userInputData.setImageGrouping(index + "");
                            userInputData.setUniqueIdentifier(key + "_" + index);
                            writeBatchJson(batchJsonLis, MENU_BATCH_PATH);
                        } else {
                            // 查询数据
                            JSONObject batchJsonLis = readBatchJson(PACKAGE_BATCH_PATH);
                            // 查询并更新JSON数据
                            int v = batchJsonLis.optInt(key, 0) + 1;
                            userInputData.setImageGrouping(v + "");
                            userInputData.setUniqueIdentifier(key + "_" + v);
                        }


                        // 赋值imageId
                        String a = StringUtil.isBlank(userInputData.getImageOfPackage()) ? "" : userInputData.getImageOfPackage() + "_";
                        userInputData.setImageId(userInputData.getParticipantId() + "_" + userInputData.getFilename() + "_" + userInputData.getLevel1Category() + "_" + userInputData.getLevel4Category() + "_" + a + userInputData.getScanType() + "_" + userInputData.getImageGrouping());


                        // 重命名文件
                        File originalFile = userInputData.getFile();
                        if (originalFile != null) {
                            // 生成新的文件名（不需要修改原始文件名）
                            String newFileName = userInputData.getImageId() + "." + getExtension(userInputData.getFile().getName());

                            // 根据level4Category分类保存图片
                            String baseOutputPath = "C:\\Output Image\\";
                            File outputPath;
                            if ("Menu".equals(userInputData.getLevel4Category())) {
                                outputPath = new File(baseOutputPath + userInputData.getParticipantId() + "\\" + "Menu\\" + userInputData.getLevel1Category() + "\\" + userInputData.getLevel4Category());
                            } else {
                                outputPath = new File(baseOutputPath + userInputData.getParticipantId() + "\\" + "Packaged\\" + userInputData.getLevel1Category() + "\\" + userInputData.getLevel4Category());
                            }

                            // 创建必要的文件夹
                            if (!outputPath.exists()) {
                                outputPath.mkdirs();
                            }

                            // 目标文件路径（使用新文件名）
                            File targetFile = new File(outputPath, newFileName);

                            // 检查目标文件夹下是否存在同名文件
//                                    File targetFile = new File(outputPath, newFileName);
                            if (targetFile.exists()) {
                                JOptionPane.showMessageDialog(uploadFrame, "目标文件夹下已存在同名文件: " + targetFile.getName(), "错误", JOptionPane.ERROR_MESSAGE);
                                // 清除当前窗体上用户上传的所有图片
                                for (UserInputData data : userInputList) {
                                    data.setFile(null);
                                    data.setFilename(null);
                                }
                                // 清除窗体上的图片路径显示
                                clearImageUploadComponents(uploadFrame);
                                return;
                            }

                            // 移动文件到目标文件夹
                            try {
                                // 直接复制原始文件到目标位置，并使用新文件名
                                Files.copy(userInputData.getFile().toPath(), targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
//                                        System.out.println("文件复制成功: " + targetFile.getAbsolutePath());

                                updateExcel(userInputData);
                                updateMasterExcel(userInputData);

                            } catch (Exception ex) {
                                JOptionPane.showMessageDialog(uploadFrame, "Excel写入失败: " + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
                                return;
                            }
                            /*if (!newFile.renameTo(targetFile)) {
                                JOptionPane.showMessageDialog(uploadFrame, "文件移动失败: " + newFile.getAbsolutePath(), "Error", JOptionPane.ERROR_MESSAGE);
                            }
                            updateExcel(userInputData);
                            updateMasterExcel(userInputData);*/
                        }
                        userInputData.setNewCreated(false);
                    }
                }

                //批次加一
                String participantIdChanged = participantIdField.getText();
                String categoryChanged = (String) categoryComboBox.getSelectedItem();
                String name4 = fcm.getLevel4BySureName(categoryChanged);
                if (!"Menu".equals(name4)) {
                    String k = participantIdChanged + "_" + name4;
                    // 查询数据
                    JSONObject batchJsonLis = readBatchJson(PACKAGE_BATCH_PATH);
                    // 查询并更新JSON数据
                    int v = batchJsonLis.optInt(k, 0) + 1;
                    batchJsonLis.put(k, v);

                    // 写回JSON文件
                    writeBatchJson(batchJsonLis, PACKAGE_BATCH_PATH);
                    int v2 = v + 1;
                    displayArea.setText("Unique Identifier: " + k + ", Image Grouping: " + v2);
                }

                //加个弹窗提示：操作成功
                JOptionPane.showMessageDialog(frame, "操作成功", "提示", JOptionPane.INFORMATION_MESSAGE);
                // 清空 upButtonPanel 中的所有内容
                upButtonPanel.removeAll();
                uploadedFileNames.clear();
                uploadedFilesDisplay.setText("");

                uploadFrame.revalidate();
                uploadFrame.repaint();
            }
        });


//                buttonPanel1.add(prevButton);
        // 添加确定按钮到窗体
        confirmButton.setPreferredSize(new Dimension(100, 30));
        buttonPanel1.add(confirmButton);
        uploadMainPanel.add(buttonPanel1, BorderLayout.SOUTH);
        uploadFrame.add(uploadMainPanel);


        // 重新布局窗体
        uploadFrame.revalidate();
        uploadFrame.repaint();

        // 隐藏当前窗体
        uploadFrame.setVisible(true);
    }

    /**
     * 添加图片上传组件到指定的JFrame中。
     * 该组件包括一个标签、一个文本框和一个上传按钮。用户点击上传按钮后，可以选择本地图片文件，
     * 并将文件路径显示在文本框中。同时，获取并显示图片的元数据。
     */
    private static UserInputData addImageUploadComponents(JFrame frame, String labelName, UserInputData inputData, JPanel panel, Integer x, int y, GridBagConstraints uploadGbc,
                                                          JComboBox<String> locationComboBox, JTextField locationOtherField, JComboBox<String> locationTypeComboBox,
                                                          JComboBox<String> packageTypeComboBox, JComboBox<String> categoryComboBox, JComboBox<String> packageMaterialComboBox,
                                                          JTextField packageMaterialOtherField, JTextField restaurantMenuField, JComboBox<String> menuMaterialComboBox,
                                                          JTextField menuMaterialOtherField, JComboBox<String> lightingComboBox, JTextField shortDescriptionField, JPanel upButtonPanel, int y2, JTextField packageTypeIfOtherField, JComboBox<String> aggressorsComboBox) {
        UserInputData resultData = inputData.clone();
        JButton uploadButton;
        JButton deleteButton;
        if (inputData.getImageOfPackage() == null || inputData.getImageOfPackage().isEmpty()) {
            uploadButton = new JButton("上传 " + "_" + labelName);
            deleteButton = new JButton("删除 " + "_" + labelName);
        } else {
            uploadButton = new JButton("上传 " + inputData.getImageOfPackage() + "_" + labelName);
            deleteButton = new JButton("删除 " + inputData.getImageOfPackage() + "_" + labelName);
        }

        //上传按钮和删除按钮放在一起
        JPanel twoButtonPanel = new JPanel();
        twoButtonPanel.setLayout(new GridBagLayout());
        twoButtonPanel.add(uploadButton);
        twoButtonPanel.add(deleteButton);

        uploadGbc.gridx = x;
        uploadGbc.gridy = y;
        panel.add(twoButtonPanel, uploadGbc);

        uploadButton.addActionListener(e -> {
            //条件判断
            resultData.setNewCreated(true);
            //上传按钮前获取最新信息
            resultData.setAggressors((String) aggressorsComboBox.getSelectedItem());
            /*resultData.setLevel4Category((String) categoryComboBox.getSelectedItem());
            FoodCategory fc = foodCategoryManager.getCategoryBySureName((String) categoryComboBox.getSelectedItem());
            resultData.setLevel4Category(fc.getLevel4());
            resultData.setLevel3Category(fc.getLevel3());
            resultData.setLevel2Category(fc.getLevel2());
            resultData.setLocation((String) locationComboBox.getSelectedItem());
            resultData.setLocationIfOther(locationOtherField.getText());
            resultData.setLocationType((String) locationTypeComboBox.getSelectedItem());
            resultData.setPackageType((String) packageTypeComboBox.getSelectedItem());
            resultData.setPackageMaterial((String) packageMaterialComboBox.getSelectedItem());
            resultData.setPackageMaterialIfOther(packageMaterialOtherField.getText());
            resultData.setRestaurantMenu(restaurantMenuField.getText());
            resultData.setMenuMaterial((String) menuMaterialComboBox.getSelectedItem());
            resultData.setMenuMaterialIfOther(menuMaterialOtherField.getText());
            resultData.setPackageTypeIfOther(packageTypeIfOtherField.getText());
            resultData.setAggressors((String) aggressorsComboBox.getSelectedItem());
            resultData.setLighting((String) lightingComboBox.getSelectedItem());
            resultData.setCameraSetting("Auto");*/


            // 使用自定义的 JFileChooser
            ImagePreviewFileChooser fileChooser = new ImagePreviewFileChooser();
            // 设置默认路径为上一次打开的文件夹
            if (lastOpenedDirectory != null) {
                fileChooser.setCurrentDirectory(new File(lastOpenedDirectory));
            }

            int result = fileChooser.showOpenDialog(frame);
            if (result == JFileChooser.APPROVE_OPTION) {
                File selectedFile = fileChooser.getSelectedFile();

                // 保存当前文件夹路径
                lastOpenedDirectory = selectedFile.getParent();

                // 检查文件名是否已经存在于 uploadedFileNames 列表中
                if (uploadedFileNames.contains(selectedFile.getName())) {
                    JOptionPane.showMessageDialog(frame, "文件 " + selectedFile.getName() + " 已经存在，请选择其他文件。", "错误", JOptionPane.ERROR_MESSAGE);
                    return; // 如果文件名已存在，弹窗提示并返回
                }

                // 添加到上传文件列表
                uploadedFileNames.add(selectedFile.getName());
                updateUploadedFilesDisplay();


                displayPhotoMetadata(selectedFile, resultData);
                // 存储文件对象到UserInputData
                resultData.setFile(selectedFile);

                // 添加查看按钮
                JButton viewButton = new JButton("查看：" + labelName + "_" + selectedFile.getName());
                viewButton.addActionListener(ev -> {
                    try {
                        Desktop.getDesktop().open(selectedFile);
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                });

                //删除
                deleteButton.addActionListener(ez -> {
                    uploadedFileNames.remove(selectedFile.getName());
                    resultData.setNewCreated(false);
                    resultData.setFile(null);
                    resultData.setDate(null);
                    resultData.setFilename(null);
                    resultData.setTimeOfDay(null);
                    resultData.setDevice(null);
                    resultData.setFlash(null);
                    upButtonPanel.remove(viewButton);
                    frame.revalidate();
                    frame.repaint();
                });

                uploadGbc.gridx = 0;
                uploadGbc.gridy = y2;
                upButtonPanel.add(viewButton, uploadGbc);

                frame.revalidate();
                frame.repaint();
            }
        });

        resultData.setUploadButton(uploadButton);
        return resultData;
    }


    private static void displayPhotoMetadata(File photoFile, UserInputData resultData) {
        try {
            Metadata metadata = ImageMetadataReader.readMetadata(photoFile);

            // 1. 文件名
            String fileName = photoFile.getName();
            String fileNameWithoutExtension = fileName.substring(0, fileName.lastIndexOf('.'));
            resultData.setFilename(fileNameWithoutExtension);

            // 2. 拍摄日期
            ExifSubIFDDirectory exifSubIFDDirectory = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);
            if (exifSubIFDDirectory != null) {
                Date date = exifSubIFDDirectory.getDate(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL);
                if (date != null) {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
                    resultData.setDate(sdf.format(date));

                    // 判断时间段
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(date);
                    int hour = calendar.get(Calendar.HOUR_OF_DAY);
                    String timeOfDay;
                    if (hour >= 6 && hour < 12) {
                        timeOfDay = "morning";
                    } else if (hour >= 12 && hour < 18) {
                        timeOfDay = "noon/afternoon";
                    } else {
                        timeOfDay = "evening";
                    }
                    resultData.setTimeOfDay(timeOfDay);
                } else {
                    throw new RuntimeException("无法获取拍摄日期");
                }
            } else {
                throw new RuntimeException("拍摄日期: 无EXIF数据");
            }

            // 3. 相机型号
            ExifIFD0Directory exifIFD0Directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
            if (exifIFD0Directory != null) {
                String model = exifIFD0Directory.getString(ExifIFD0Directory.TAG_MODEL);
                resultData.setDevice(model);
            } else {
                throw new RuntimeException("相机型号: 无EXIF数据");
            }

            // 4. 闪光灯模式（简化版）
            ExifSubIFDDirectory subDir = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);
            if (subDir != null && subDir.containsTag(ExifSubIFDDirectory.TAG_FLASH)) {
                int flash = subDir.getInt(ExifSubIFDDirectory.TAG_FLASH);
                boolean isFlashOn = isFlashActivated(flash);
                resultData.setFlash(isFlashOn ? "ON" : "OFF");
            } else {
                throw new RuntimeException("闪光灯模式: 无EXIF数据");
            }
        } catch (Exception e) {
            throw new RuntimeException("读取照片元数据失败", e);
        }
    }

    // 简化的闪光灯状态判断
    private static boolean isFlashActivated(int flashValue) {
        // 根据EXIF规范，闪光灯触发的最低有效位为1表示闪光灯触发
        return (flashValue & 0x1) == 0x1;
    }

    private static void updateExcel(UserInputData userInputData) {
        String currentDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String level4Category = userInputData.getLevel4Category();
        String baseOutputPath = "C:\\Output Image\\";
        File categoryFolder;
        if ("Menu".equals(level4Category)) {
            categoryFolder = new File(baseOutputPath + userInputData.getParticipantId() + "\\" + "Menu\\" + userInputData.getLevel1Category() + "\\" + level4Category);
        } else {
            categoryFolder = new File(baseOutputPath + userInputData.getParticipantId() + "\\" + "Packaged\\" + userInputData.getLevel1Category() + "\\" + level4Category);
        }

        File excelFile = new File(categoryFolder, "Metadata_" + userInputData.getParticipantId() + "_" + level4Category + "_" + currentDate + ".xlsx");
        Workbook workbook;
        if (excelFile.exists()) {
            try (FileInputStream fis = new FileInputStream(excelFile)) {
                workbook = new XSSFWorkbook(fis);
            } catch (IOException e) {
                throw new RuntimeException("无法读取Excel文件", e);
            }
        } else {
            workbook = new XSSFWorkbook();
        }

        Sheet sheet = workbook.getSheet("Metadata");
        if (sheet == null) {
            sheet = workbook.createSheet("Metadata");
        }

        Row headerRow = sheet.getRow(0);
        if (headerRow == null) {
            headerRow = sheet.createRow(0);
            String[] headers = {"Date", "Country", "Language", "Participant ID", "Device", "Filename", "Level 1 Category", "Level 2 Category", "Level 3 Category", "Level 4 Category", "Short Description", "Image ID", "Location", "Location If Other", "Location Type", "Package Type", "Package Type if Other", "Image of Package", "Package Material", "Package Material If Other", "Menu Material", "Menu Material If Other", "Lighting", "Time of Day", "Flash", "Restaurant (Menu Only)", "Cuisine/Country of Origin", "Aggressors", "Camera Setting", "Scan Type", "Image Grouping", "Unique Identifier"};
            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
            }
        }

        int rowCount = sheet.getLastRowNum() + 1;
        Row row = sheet.createRow(rowCount);
        row.createCell(0).setCellValue(userInputData.getDate());
        row.createCell(1).setCellValue(userInputData.getCountry());
        row.createCell(2).setCellValue(userInputData.getLanguage());
        row.createCell(3).setCellValue(userInputData.getParticipantId());
        row.createCell(4).setCellValue(userInputData.getDevice());
        row.createCell(5).setCellValue(userInputData.getFilename());
        row.createCell(6).setCellValue(userInputData.getLevel1Category());
        row.createCell(7).setCellValue(userInputData.getLevel2Category());
        row.createCell(8).setCellValue(userInputData.getLevel3Category());
        row.createCell(9).setCellValue(userInputData.getLevel4Category());
        row.createCell(10).setCellValue(userInputData.getShortDescription());
        row.createCell(11).setCellValue(userInputData.getImageId());
        row.createCell(12).setCellValue(userInputData.getLocation());
        row.createCell(13).setCellValue(userInputData.getLocationIfOther());
        row.createCell(14).setCellValue(userInputData.getLocationType());
        if (userInputData.getLevel4Category().equals("Menu")) {
            row.createCell(15).setCellValue("");
            row.createCell(16).setCellValue("");
            row.createCell(17).setCellValue("");
            row.createCell(18).setCellValue("");
            row.createCell(19).setCellValue("");
            row.createCell(20).setCellValue(userInputData.getMenuMaterial());
            row.createCell(21).setCellValue(userInputData.getMenuMaterialIfOther());
        } else {
            row.createCell(15).setCellValue(userInputData.getPackageType());
            row.createCell(16).setCellValue(userInputData.getPackageTypeIfOther());
            row.createCell(17).setCellValue(userInputData.getImageOfPackage());
            row.createCell(18).setCellValue(userInputData.getPackageMaterial());
            row.createCell(19).setCellValue(userInputData.getPackageMaterialIfOther());
            row.createCell(20).setCellValue("");
            row.createCell(21).setCellValue("");
        }
        row.createCell(22).setCellValue(userInputData.getLighting());
        row.createCell(23).setCellValue(userInputData.getTimeOfDay());
        row.createCell(24).setCellValue(userInputData.getFlash());
        if (userInputData.getLevel4Category().equals("Menu")) {
            row.createCell(25).setCellValue(userInputData.getRestaurantMenu());
        } else {
            row.createCell(25).setCellValue("");
        }
        row.createCell(26).setCellValue(userInputData.getCuisineCountryOfOrigin());
        if (userInputData.getScanType().equals("Freeform")) {
            row.createCell(27).setCellValue(userInputData.getAggressors());
        } else {
            row.createCell(27).setCellValue("");
        }
        row.createCell(28).setCellValue(userInputData.getCameraSetting());
        row.createCell(29).setCellValue(userInputData.getScanType());
        row.createCell(30).setCellValue(userInputData.getImageGrouping());
        row.createCell(31).setCellValue(userInputData.getUniqueIdentifier());

        try (FileOutputStream fos = new FileOutputStream(excelFile)) {
            workbook.write(fos);
        } catch (IOException e) {
            throw new RuntimeException("无法写入Excel文件", e);
        }
    }

    private static void updateMasterExcel(UserInputData userInputData) {
        String currentDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String baseOutputPath = "C:\\Output Image\\" + userInputData.getParticipantId() + "\\";
        File masterExcelFile = new File(baseOutputPath, userInputData.getParticipantId() + "_" + currentDate + ".xlsx");
        Workbook workbook;
        if (masterExcelFile.exists()) {
            try (FileInputStream fis = new FileInputStream(masterExcelFile)) {
                workbook = new XSSFWorkbook(fis);
            } catch (IOException e) {
                throw new RuntimeException("无法读取Excel文件", e);
            }
        } else {
            workbook = new XSSFWorkbook();
        }

        Sheet sheet = workbook.getSheet("Master");
        if (sheet == null) {
            sheet = workbook.createSheet("Master");
        }

        Row headerRow = sheet.getRow(0);
        if (headerRow == null) {
            headerRow = sheet.createRow(0);
            String[] headers = {"Date", "Country", "Language", "Participant ID", "Device", "Filename", "Level 1 Category", "Level 2 Category", "Level 3 Category", "Level 4 Category", "Short Description", "Image ID", "Location", "Location If Other", "Location Type", "Package Type", "Package Type if Other", "Image of Package", "Package Material", "Package Material If Other", "Menu Material", "Menu Material If Other", "Lighting", "Time of Day", "Flash", "Restaurant (Menu Only)", "Cuisine/Country of Origin", "Aggressors", "Camera Setting", "Scan Type", "Image Grouping", "Unique Identifier"};
            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
            }
        }

        int rowCount = sheet.getLastRowNum() + 1;
        Row row = sheet.createRow(rowCount);
        row.createCell(0).setCellValue(userInputData.getDate());
        row.createCell(1).setCellValue(userInputData.getCountry());
        row.createCell(2).setCellValue(userInputData.getLanguage());
        row.createCell(3).setCellValue(userInputData.getParticipantId());
        row.createCell(4).setCellValue(userInputData.getDevice());
        row.createCell(5).setCellValue(userInputData.getFilename());
        row.createCell(6).setCellValue(userInputData.getLevel1Category());
        row.createCell(7).setCellValue(userInputData.getLevel2Category());
        row.createCell(8).setCellValue(userInputData.getLevel3Category());
        row.createCell(9).setCellValue(userInputData.getLevel4Category());
        row.createCell(10).setCellValue(userInputData.getShortDescription());
        row.createCell(11).setCellValue(userInputData.getImageId());
        row.createCell(12).setCellValue(userInputData.getLocation());
        row.createCell(13).setCellValue(userInputData.getLocationIfOther());
        row.createCell(14).setCellValue(userInputData.getLocationType());
        if (userInputData.getLevel4Category().equals("Menu")) {
            row.createCell(15).setCellValue("");
            row.createCell(16).setCellValue("");
            row.createCell(17).setCellValue("");
            row.createCell(18).setCellValue("");
            row.createCell(19).setCellValue("");
            row.createCell(20).setCellValue(userInputData.getMenuMaterial());
            row.createCell(21).setCellValue(userInputData.getMenuMaterialIfOther());
        } else {
            row.createCell(15).setCellValue(userInputData.getPackageType());
            row.createCell(16).setCellValue(userInputData.getPackageTypeIfOther());
            row.createCell(17).setCellValue(userInputData.getImageOfPackage());
            row.createCell(18).setCellValue(userInputData.getPackageMaterial());
            row.createCell(19).setCellValue(userInputData.getPackageMaterialIfOther());
            row.createCell(20).setCellValue("");
            row.createCell(21).setCellValue("");
        }
        row.createCell(22).setCellValue(userInputData.getLighting());
        row.createCell(23).setCellValue(userInputData.getTimeOfDay());
        row.createCell(24).setCellValue(userInputData.getFlash());
        if (userInputData.getLevel4Category().equals("Menu")) {
            row.createCell(25).setCellValue(userInputData.getRestaurantMenu());
        } else {
            row.createCell(25).setCellValue("");
        }
        row.createCell(26).setCellValue(userInputData.getCuisineCountryOfOrigin());
        if (userInputData.getScanType().equals("Freeform")) {
            row.createCell(27).setCellValue(userInputData.getAggressors());
        } else {
            row.createCell(27).setCellValue("");
        }
        row.createCell(28).setCellValue(userInputData.getCameraSetting());
        row.createCell(29).setCellValue(userInputData.getScanType());
        row.createCell(30).setCellValue(userInputData.getImageGrouping());
        row.createCell(31).setCellValue(userInputData.getUniqueIdentifier());

        try (FileOutputStream fos = new FileOutputStream(masterExcelFile)) {
            workbook.write(fos);
        } catch (IOException e) {
            throw new RuntimeException("无法写入Excel文件", e);
        }
    }

    // 读取JSON文件的方法
    private static JSONObject readBatchJson(String path) {
        JSONObject jsonObject = new JSONObject();
//        File jsonFile = new File("C:\\img log\\batch.json");
        File jsonFile = new File(path);
        File parentDir = jsonFile.getParentFile();
        if (!parentDir.exists()) {
            parentDir.mkdirs(); // 创建所有不存在的父目录
        }
        // 检查文件是否存在
        if (!jsonFile.exists()) {
            try {
                // 创建新文件
                jsonFile.createNewFile();
                // 写入空对象 {}
                try (FileWriter writer = new FileWriter(jsonFile)) {
                    writer.write("{}");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return jsonObject; // 返回空的 JSONObject
        }

        // 如果文件存在，读取并返回 JSON 数据
        try (FileReader reader = new FileReader(jsonFile)) {
            jsonObject = new JSONObject(new JSONTokener(reader));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return jsonObject;
    }


    // 写回JSON文件的方法
    private static void writeBatchJson(JSONObject jsonObject, String path) {
//        try (FileWriter writer = new FileWriter("C:\\img log\\batch.json")) {
        try (FileWriter writer = new FileWriter(path)) {
            writer.write(jsonObject.toString(4));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static String getExtension(String filename) {
        int lastDotIndex = filename.lastIndexOf('.');
        if (lastDotIndex == -1) {
            return ""; // 没有扩展名
        }
        return filename.substring(lastDotIndex + 1);
    }

    private static void clearImageUploadComponents(JFrame frame) {
        // 假设图片上传组件的文本框名称为 "Normal", "Freeform", "Normal1", "Normal2", "Freeform1", "Freeform2", "Barcode"
        String[] componentNames = {"Normal", "Freeform", "Normal1", "Normal2", "Freeform1", "Freeform2", "Barcode"};
        for (String componentName : componentNames) {
            for (Component component : frame.getContentPane().getComponents()) {
                if (component instanceof JTextField && component.getName().equals(componentName)) {
                    ((JTextField) component).setText("");
                }
            }
        }
    }

    // 新增方法：更新已上传文件显示
    private static void updateUploadedFilesDisplay() {
        StringBuilder sb = new StringBuilder();
        for (String fileName : uploadedFileNames) {
            sb.append(fileName).append("\n");
        }
        uploadedFilesDisplay.setText(sb.toString());
    }

    private static void clearUploadFrameData(JFrame uploadFrame) {
        // 遍历所有组件
        for (Component component : uploadFrame.getContentPane().getComponents()) {
            if (component instanceof JTextField) {
                // 清除文本框内容
                ((JTextField) component).setText("");
            } else if (component instanceof JComboBox) {
                // 清除下拉列表的选中项
                ((JComboBox<?>) component).setSelectedIndex(0);
            } else if (component instanceof JPanel) {
                // 递归清除面板中的组件
                clearPanelData((JPanel) component);
            }
        }
    }

    private static void clearPanelData(JPanel panel) {
        for (Component component : panel.getComponents()) {
            if (component instanceof JTextField) {
                ((JTextField) component).setText("");
            } else if (component instanceof JComboBox) {
                ((JComboBox<?>) component).setSelectedIndex(0);
            } else if (component instanceof JPanel) {
                clearPanelData((JPanel) component);
            }
        }
    }

    // 在集合中查找目标元素的索引
    private static int findIndex(Set<String> set, String target) {
        int index = 0;
        for (String item : set) {
            if (item.equals(target)) {
                return index;
            }
            index++;
        }
        return -1;  // 未找到
    }

}